package com.ds.infrastructure.hyperspace.console.controller;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import com.ds.infrastructure.hyperspace.console.entity.enums.TbNodeExecuteLogEnum;
import com.ds.infrastructure.hyperspace.console.entity.enums.TbPublicEnum;
import com.ds.infrastructure.hyperspace.console.entity.page.TbPageWhere;
import com.ds.infrastructure.hyperspace.console.entity.table.TbContainerConfig;
import com.ds.infrastructure.hyperspace.console.entity.table.TbNodeExecuteLog;
import com.ds.infrastructure.hyperspace.console.entity.table.TbReleaseTask;
import com.ds.infrastructure.hyperspace.console.exceptions.HyperspaceException;
import com.ds.infrastructure.hyperspace.console.model.request.log.ListLogForm;
import com.ds.infrastructure.hyperspace.console.model.response.log.ListLogVO;
import com.ds.infrastructure.hyperspace.console.model.response.log.LogInfoVO;
import com.ds.infrastructure.hyperspace.console.model.response.result.JsonResult;
import com.ds.infrastructure.hyperspace.console.model.response.result.JsonResultData;
import com.ds.infrastructure.hyperspace.console.model.response.result.JsonResultOk;
import com.ds.infrastructure.hyperspace.console.service.inf.IContainerConfigService;
import com.ds.infrastructure.hyperspace.console.service.inf.INodeExecuteLogService;
import com.ds.infrastructure.hyperspace.console.service.inf.IReleaseTaskService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;


/**
 * @author: yaozhendong
 * @create: 2019-10-28 16:15
 **/
@Slf4j
@RestController
@RequestMapping(value = "/log", produces = {"application/json;charset=UTF-8"})
@Api(value = "Manager Log Controller", tags = "日志管理")
public class LogController {
    @Autowired
    INodeExecuteLogService iNodeExecuteLogService;
    @Autowired
    IReleaseTaskService iReleaseTaskService;
    @Autowired
    IContainerConfigService iContainerConfigService;

    @PostMapping(value = "/nodeExecuteLogList")
    @ApiOperation(value = "节点执行日志列表")
    public JsonResultData<ListLogVO> nodeExecuteLogList(@RequestBody @Valid ListLogForm form) {
        ListLogVO result = new ListLogVO();
        Integer completedState = getCompletedState(form, result);
        if (TbPublicEnum.TASK_COMPLETE_STATE.INIT.value.equals(completedState)) {
            return JsonResultData.build(result);
        }
        TbNodeExecuteLog where = ListLogForm.toEntity(form);
        List<TbNodeExecuteLog> tbLogList = iNodeExecuteLogService.getList(where, null, TbPageWhere.newPage4All());
        List<LogInfoVO> dataList = new ArrayList<>();
        tbLogList.forEach(item -> dataList.add(LogInfoVO.toVO(item)));
        result.setLogs(dataList);
        return JsonResultData.build(result);
    }

    private Integer getCompletedState(ListLogForm form, ListLogVO logVO) {
        if (TbNodeExecuteLogEnum.TASK_TYPE.RELEASE_TASK.code.equals(form.getTaskType())) {
            TbReleaseTask tbReleaseTask = iReleaseTaskService.get(form.getTaskId());
            if (tbReleaseTask == null) {
                throw new HyperspaceException("没有找到对应的网关配置数据发送任务记录，releaseTaskId=" + form.getTaskId());
            }
            TbContainerConfig tbContainerConfig = iContainerConfigService.getOrThrow(tbReleaseTask.getContainerConfigId());
            logVO.setConfigVersion(tbContainerConfig.getConfigVersion());
            logVO.setCompletedState(tbReleaseTask.getCompleteState());
            logVO.setUserId(tbReleaseTask.getUserId());
            logVO.setUserName(tbReleaseTask.getUserName());
            return tbReleaseTask.getCompleteState();
        }
        throw new HyperspaceException("没有找到对应的任务类型，taskType=" + form.getTaskType());
    }

    /**
     * 动态调整-项目日志输出级别
     *
     * @param allLevel    全局日志级别
     * @param singleLevel 某个类日志级别
     * @param singlePath  需要单独设置日志输出级别的类的全限定名（例：com.ds.infrastructure.hyperspace.console.dao.mapper）
     * @return
     */
    @ApiIgnore
    @GetMapping(value = "changeLevel")
    public JsonResult changeLevel(String allLevel, String singleLevel, String singlePath) {
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
        if (!StringUtils.isEmpty(allLevel)) {
            //设置全局日志级别
            ch.qos.logback.classic.Logger logger = loggerContext.getLogger("root");
            logger.setLevel(Level.toLevel(allLevel));
        }
        if (!StringUtils.isEmpty(singleLevel)) {
            //设置某个类日志级别-可以实现定向日志级别调整
            ch.qos.logback.classic.Logger vLogger = loggerContext.getLogger(singlePath);
            if (vLogger != null) {
                vLogger.setLevel(Level.toLevel(singleLevel));
            }
        }
        return JsonResultOk.SUCCESS;
    }

}
